package main

import (
	"fmt"
	"math/rand"
	"strconv"
	"strings"
	"time"
)

/* 1. 请将这段二进制翻译成中文(unicode编码), b并打印出翻译过程(比如 二进制: 1000 1000 0110 0011, unicode: U+8863, 字符: 衣)
	1000 1000 0110 0011
	0110 0111 0000 1101
	0101 0101 1001 1100
	0110 1011 0010 0010
	0111 1010 0111 1111
	0100 1110 0010 1101
	0101 0110 1111 1101
	0111 1110 1010 0010
*/
func ConversionBinToUnicode() {
	binStr := `
		1000 1000 0110 0011
		0110 0111 0000 1101
		0101 0101 1001 1100
		0110 1011 0010 0010
		0111 1010 0111 1111
		0100 1110 0010 1101
		0101 0110 1111 1101
		0111 1110 1010 0010
	`
	// 按照 \n 对字符串进行切割，分割出每一个行
	for _, binLineStr := range strings.Split(binStr, "\n") {

		// 空行跳过
		if len(binLineStr) == 0 || binLineStr == "\t" {
			continue
		}

		// 排除字符串前后的空格
		binLineStr = strings.TrimSpace(binLineStr)

		// 字符串 To 二进制
		var result int
		var binBit = 15
		for _, binChar := range binLineStr {

			// 跳过空格字符
			if binChar == 32 {
				continue
			}

			// 将每一个字符转换为 int 类型
			binCharInt, err  := strconv.Atoi(string(binChar))
			if err != nil {
				return
			}

			// 二进制位计算
			result += binCharInt << binBit
			binBit--
		}
		fmt.Printf("二进制: %s, Unicode: %U, 字符: %c\n", binLineStr,result,result)
	}

}

/*
	2.写一个单位转换的函数, 同学只需要把函数逻辑部分编写完成,
	测试方法: main 函数内部 通过HumanBytesLoaded(1024)调用

	HumanBytesLoaded 单位转换(B KB MB GB TB EB)
	func HumanBytesLoaded(bytesLength int64) string {
		var resp string

		// bytesLength
		fmt.Printf("需要转换的值: %dB", bytesLength)

		// 单位转换的逻辑 将 bytesLength ==> resp, 比如 1024 ==> 1KB

		// 返回转换的结果
		return resp
	}
*/
func HumanBytesLoaded(bytesLength int64) string {
	var resp string

	// 提示语
	fmt.Printf("需要转换的值: %d B\n", bytesLength)

	// 定义单位常量
	const (
		KB = 1024 << (iota * 10)
		MB
		GB
		TB
	)

	// 计算结果
	switch  {
		case bytesLength >= TB :
			resp = fmt.Sprintf("转换后的值为: %v TB", bytesLength / TB)
		case bytesLength >= GB :
			resp = fmt.Sprintf("转换后的值为: %v GB", bytesLength / GB)
		case bytesLength >= MB :
			resp = fmt.Sprintf("转换后的值为: %v MB", bytesLength / MB)
		case bytesLength >= KB :
			resp = fmt.Sprintf("转换后的值为: %v KB", bytesLength / KB)
		default:
			resp = fmt.Sprintf("无法计算，检查数据")
	}

	// 返回转换的结果
	return resp
}

/*
	3.做一个抽卡程序, 中奖率万分之一, 看看你多少个10连能中奖
	请回答如下问题, 比如: a + b =:  m
	恭喜你 回答正确，随机获取n[1~10]的抽奖机会
	当前是你第1次抽奖: 抽奖结果 未中奖
	当前是你第2次抽奖. 抽奖结果 未中奖
	当前是你第3次抽奖. 抽奖结果 未中奖
	...
*/
func Add(x,y int) int{
	return x+y
}
func GameZone(){
	fmt.Printf("抽奖游戏中心，回答正确，可以抽奖！! !\n")
	for {
		// 计算题目和中奖号码
		rand.Seed(time.Now().Unix())
		result := rand.Intn(10000)
		x := rand.Intn(10)
		y := rand.Intn(10)

		// 用户开始输入
		var userAnswer int
		var userChoice string
		fmt.Printf("请输入回答：%v + %v = ", x,y)
		_, err := fmt.Scan(&userAnswer)
		if err != nil {
			fmt.Printf("输入错误，是否继续？ 任意键继续，q退出")
			_,_ = fmt.Scan(&userChoice)
			switch userChoice {
			case "q":
				fmt.Println("欢迎下次再来！")
				return
			default:
				continue
			}
		}

		// 计算用户输入结果
		res := Add(x,y)
		if userAnswer == res {

			// 回答正确
			count := rand.Intn(10)
			fmt.Printf("回答正确，恭喜你获得 %v 次抽奖机会。\n", count)
			fmt.Printf("大奖编号为: %v\n",result)
			for i:=1;i<=count;i++ {
				r := rand.Intn(10000)
				if r == result {
					fmt.Printf("当前是你第 %02d 次抽奖: 你的奖号为：%04d 抽奖结果 中奖啦\n", i, r )
					break
				}
				fmt.Printf("当前是你第 %02d 次抽奖: 你的奖号为：%04d 抽奖结果 未中奖\n", i, r)
				time.Sleep(time.Millisecond * 500)
			}
		} else {

			// 回答错误
			fmt.Printf("回答错误是否继续？ 任意键继续，q退出")
			_,_ = fmt.Scan(&userChoice)
			switch userChoice {
			case "q":
				fmt.Println("欢迎下次再来！")
				return
			default:
				continue
			}
		}

		// 未中奖是否继续
		fmt.Printf("未中奖，是否继续？ 任意键继续，q退出")
		_,_ = fmt.Scan(&userChoice)
		switch userChoice {
			case "q":
				fmt.Println("欢迎下次再来！")
				return
			default:
				continue
		}
	}
}


func main(){

	fmt.Println("Question 1: ")
	ConversionBinToUnicode()
	fmt.Println()

	fmt.Println("Question 2: ")
	resp := HumanBytesLoaded(4096)
	fmt.Println(resp)
	fmt.Println()

	fmt.Println("Question 3: ")
	GameZone()
}